#include<iostream>
using namespace std;

// 拷贝构造函数和拷贝赋值运算符考虑深拷贝场景
class Example{
    public:
        Example()
        {
            // 动态内存内容初始化
            data = new int[10]();
            cout<<"调用默认构造函数"<<endl;
        }

        Example(const Example& other)
        {
            // 拷贝构造函数，考虑深拷贝场景，当数据成员是指针的时候，不能简单的做指针赋值，需要新申请一块内存，做拷贝
            data = new int[10]();
            std::copy(other.data, other.data + 10, data);
            cout<<"调用拷贝构造函数"<<endl;
        }

        Example& operator=(const Example& other)
        {
            // 拷贝赋值运算符，如果是自赋值，直接返回。
            // 如果不是自赋值，先把对象中原始资源删除掉，然后做复制
            if (this == &other) {
                return *this;
            }
            // 先分配新内存，然后再释放旧内存，然后复制
            int* newData = new int[10]();
            std::copy(other.data, other.data + 10, newData);
            if (data != nullptr) {
                delete[] data;
            }
            data = newData;

            cout<<"调用拷贝赋值操作符"<<endl;
            return *this;
        }

        ~Example()
        {
            delete[] data;
            cout<<"调用析构函数"<<endl;
        }
    private:
        int* data;
};


int main()
{
    Example ex1;
    Example ex2 = ex1;
    Example ex3;
    ex3 = ex2;
}

/*
    改进建议：
    1、遵循ROT，rull of three（三原则），显示定义析构函数、拷贝构造和拷贝赋值运算符
    2、拷贝赋值运算符中，先申请资源再释放
    3、内存初始化时，要确保动态内存内容有效
*/